#pragma once
#include <map>

namespace util{
    template<typename K, typename T>
    struct myTreeNode{
        myTreeNode(K k, T* d, myTreeNode * p) : key(k), data(d), parent(p){
        }

        myTreeNode(K k, T* d) : key(k), data(d), parent(nullptr){}

        myTreeNode() :key((K)NULL), data(nullptr), parent(nullptr){}
        K key;
        T * data;
        myTreeNode<K, T> * parent;
        std::map<K, myTreeNode<K, T> *> children;
    };

    template<typename K, typename T>
    struct myTree{

        myTree(K key, T rootData){
            root = new myTreeNode<K,T>(key, new T(rootData));
        }

        myTree(){
            root = nullptr;
        }

        ~myTree(){
            if(root != nullptr)
                Free(root);
        }

        static void addChild(const myTreeNode<K, T> *& parent, K key, T * data){
            parent->children.at(key) = new myTreeNode<K, T>(key, data, parent); 
        }
        static void Free(myTreeNode<K, T> * node){
            for(typename::std::map<K, myTreeNode<K, T> *>::iterator it = node->children.begin(); it != node->children.end(); it++){
                if(it->second != nullptr)
                    Free(it->second);
            }
            if(node->data != nullptr){
                node->data->~T();
                node->data = nullptr;
            }
            delete node;
            node = nullptr;
        }
        myTreeNode<K, T> * root;
    };
}